package com.srit.core.sql;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;

import com.srit.forecast.bean.Report;

/**
 * @author guan 范型 反射取数据库
 * @param <T>
 */
public class BaseResultSetExtractor<T> implements ResultSetExtractor<T> {
	protected static Logger logger = LoggerFactory
			.getLogger(BaseResultSetExtractor.class);

	private Class<T> entityClass;

	public BaseResultSetExtractor() {
		entityClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@Override
	public T extractData(ResultSet rs) throws SQLException, DataAccessException {
		// System.out.println(entityClass);
		T t = null;
		try {
			t = entityClass.newInstance();
			Field[] fields = entityClass.getDeclaredFields();
			BeanField[] beanFields = new BeanField[fields.length];
			for (int i = 0; i < fields.length; i++) {
				beanFields[i] = new BeanField(fields[i]);
			}
			for (int i = 0; i < beanFields.length; i++) {
				// System.out.println("类型名:" + beanFields[i].getTypeName());
				// System.out.println(beanFields[i].getMethodName());
				if (beanFields[i].getName()
						.equalsIgnoreCase("serialVersionUID")) {
					continue;
				}
				Method method = entityClass.getDeclaredMethod(beanFields[i]
						.getMethodName(), beanFields[i].getField().getType());
				
				// System.out.println(method);
				if ("java.lang.String".equals(beanFields[i].getTypeName())) {
					method.invoke(t, rs.getString(beanFields[i].getName()));
				} else if ("java.lang.Integer".equals(beanFields[i]
						.getTypeName())
						|| "int".equals(beanFields[i].getTypeName())) {
					method.invoke(t, rs.getInt(beanFields[i].getName()));
				} else if ("java.util.Date".equals(beanFields[i].getTypeName())) {
					method.invoke(t, rs.getDate(beanFields[i].getName()));
				} else {
					logger.info(beanFields[i].getType() + "未被反射注入");
				}
			}

		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return t;
	}

	public static void main(String[] args) throws DataAccessException,
			SQLException {
		TestExtractor test = new TestExtractor();
		test.extractData(null);
	}

}

class TestExtractor extends BaseResultSetExtractor<Report> {
}
